import { useRequest } from "ahooks";
import { Empty, Spin } from "antd";
import { PropsWithChildren, ReactNode, useMemo } from "react";
import { RequestRenderContext } from "./RequestRenderContext";

export interface IRequestRenderProps<Req, Res> {
  request: (p?: Req) => Promise<Res>;
  deps?: Req;
  manual?: boolean;
  debounceWait?: number;
  emptyFn?: (res?: Res, p?: Req) => boolean;
  loadingNode?: ReactNode;
  emptyNode?: ReactNode;
}

export function RequestRender<Req, Res>(
  props: PropsWithChildren<IRequestRenderProps<Req, Res>>
) {
  const {
    request,
    deps,
    manual,
    debounceWait,
    emptyFn,
    loadingNode,
    emptyNode,
  } = props;

  const { data, loading, refresh, } = useRequest(() => request(deps), {
    debounceWait: debounceWait,
    refreshDeps: [deps],
    manual: manual,
  });

  const isEmpty = useMemo(() => {
    if (typeof emptyFn === "function") {
      return emptyFn?.(data, deps);
    }

    return false;
  }, [data, emptyFn, deps]);

  if (loading) {
    if (loadingNode) {
      return loadingNode;
    }

    return (
      <div className="flex flex-row justify-center">
        <Spin />
      </div>
    );
  }

  if (isEmpty) {
    if (emptyNode) {
      return emptyNode;
    }

    return (
      <div className="flex flex-row justify-center">
        <Empty />
      </div>
    );
  }

  return (
    <RequestRenderContext.Provider value={{ data, manual, refresh }}>
      {props.children}
    </RequestRenderContext.Provider>
  );
}
